/****************************************************************************************
 * Copyright (c) 2010~2012 All Rights Reserved by
 *  G-Net Integrated Service Co.,  Ltd. 
 ****************************************************************************************/
/**
 * @file JSONUtil.java
 * @author wenhui.li
 * @date 2012-9-26 下午8:00:22 
 * Revision History 
 *     - 2012-9-26: change content for what reason
 ****************************************************************************************/
package com.oc.mba.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * @brief JSON操作的辅助类
 * 
 *        功能描述： -# JSON格式转换成JSONObject -# JSON格式和Map -# Map转换为JSON -#
 *        String格式转换为JSON -# Boolean转换为JSON -# int转换为JSON
 */
public class JSONUtil {

	/**
	 * @brief 将 Map<String, String> 转换为 JSON
	 * @param map
	 *            要转换的Map
	 * @return 转换后的Sting
	 */
	public static String mts(Map<String, Object> map) {
		if (map.isEmpty()) {
			return "{}";
		}
		final StringBuilder sb = new StringBuilder(map.size() << 4); // 4次方
		sb.append('{');
		final Set<String> keys = map.keySet();
		for (final String key : keys) {
			final Object value = map.get(key);
			sb.append('\"');
			sb.append(key); // 不能包含特殊字符
			sb.append('\"');
			sb.append(':');
			sb.append(toJson(value)); // 循环引用的对象会引发无限递归
			sb.append(',');
		}
		// 将最后的 ',' 变为 '}':
		sb.setCharAt(sb.length() - 1, '}');
		return sb.toString();
	}

	/**
	 * @brief 将JSON格式的字串转换为Map
	 * @param jsonString
	 *            要转换的String
	 * @return 转换后的Map
	 */
	public static Map<String, Object> stm(String jsonString) {
		JSONObject jsonObject;
		try {
			jsonObject = new JSONObject(jsonString);
			@SuppressWarnings("unchecked")
			Iterator<String> keyIter = jsonObject.keys();
			String key;
			Object value;
			Map<String, Object> valueMap = new HashMap<String, Object>();
			while (keyIter.hasNext()) {
				key = (String) keyIter.next();
				if (isNotNull(key)) {
					value = jsonObject.get(key);
					if (value != null) {
						valueMap.put(key, value);
					}
				}
			}
			return valueMap;
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @brief 将JSON格式字符串装换成Object对象
	 * @param jsonString
	 *            要转换的String
	 * @return 转换后的JOSN对象
	 */
	public static JSONObject sto(String jsonString) {
		JSONObject object = null;
		try {
			object = new JSONObject(jsonString);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return object;
	}

	/**
	 * @brief 把对象封装为JSON格式
	 * @param o
	 *            要转换的object
	 * @return 转换后的JSON
	 */
	@SuppressWarnings("unchecked")
	public static String toJson(final Object o) {
		if (o == null) {
			return "null";
		}
		if (o instanceof String) // String
		{
			return string2Json((String) o);
		}
		if (o instanceof Boolean) // Boolean
		{
			return boolean2Json((Boolean) o);
		}
		if (o instanceof Number) // Number
		{
			return number2Json((Number) o);
		}
		if (o instanceof HashMap) // Map
		{
			return mts((HashMap<String, Object>) o);
		}
		if (o instanceof Collection) // List Set
		{
			return collection2Json((Collection<Object>) o);
		}
		if (o instanceof Object[]) // 对象数组
		{
			return array2Json((Object[]) o);
		}
		throw new RuntimeException("不支持的类型: " + o.getClass().getName());
	}

	/**
	 * @brief 将 Number 表示为 JSON格式
	 * @param number
	 *            Number
	 * @return JSON格式
	 */
	static String number2Json(final Number number) {
		return number.toString();
	}

	/**
	 * @brief 将 Boolean 表示为 JSON格式
	 * @param bool
	 *            Boolean
	 * @return JSON格式
	 */
	static String boolean2Json(final Boolean bool) {
		return bool.toString();
	}

	/**
	 * @brief 将 Collection 编码为 JSON 格式 (List,Set)
	 * @param c
	 *            Collection
	 * @return String格式
	 */
	static String collection2Json(final Collection<Object> c) {
		final Object[] arrObj = c.toArray();
		return toJson(arrObj);
	}

	/**
	 * @brief 将 String 对象编码为 JSON格式，只需处理好特殊字符
	 * @param s
	 *            String 对象
	 * @return JSON格式
	 */
	public static String string2Json(final String s) {
		final StringBuilder sb = new StringBuilder(s.length() + 20);
		sb.append('\"');
		for (int i = 0; i < s.length(); i++) {
			final char c = s.charAt(i);
			sb.append(c);
		}
		sb.append('\"');
		return sb.toString();
	}

	/**
	 * @brief 将数组编码为 JSON 格式
	 * @param array
	 *            数组
	 * @return JSON 格式
	 */
	static String array2Json(final Object[] array) {
		if (array.length == 0) {
			return "[]";
		}
		final StringBuilder sb = new StringBuilder(array.length << 4); // 4次方
		sb.append('[');
		for (final Object o : array) {
			sb.append(toJson(o));
			sb.append(',');
		}
		// 将最后添加的 ',' 变为 ']':
		sb.setCharAt(sb.length() - 1, ']');
		return sb.toString();
	}

	/**
	 * @brief boolean类型转String类型
	 * @param boolea
	 *            转换对象
	 * @return String 转换后的字符串
	 */
	public static String boolean2String(boolean boolea) {
		if (boolea) {
			return "1";
		} else {
			return "0";
		}
	}

	/**
	 * @brief boolean类型转int类型
	 * @param boolea
	 *            转换对象
	 * @return int 转换后的int型
	 */
	public static int boolean2int(boolean boolea) {
		if (boolea) {
			return 1;
		} else {
			return 0;
		}
	}

	/**
	 * @brief int类型转boolean类型
	 * @param m
	 *            转换对象
	 * @return boolean true表示1，false表示0
	 */
	public static boolean int2boolean(int m) {
		if (m == 0) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * @brief 判断字符串全部为数字
	 * @param str
	 *            字符串
	 * @return boolean true表示全为数字，false表示否
	 */
	public static boolean isNumeric(String str) {
		for (int i = 0; i < str.length(); i++) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * @brief 判读输入的字符串参数是否为空
	 * @param str
	 *            输入的字符参数
	 * @return 返回字符串是否为空 true：字符串为空 false：字符串不为空
	 */
	public static boolean isNotNull(String str) {
		if (str != null && str.length() != 0) {
			return true;
		} else {
			return false;
		}
	}
}
